<template>
  <Form
    as="div"
    ref="form"
    class="form-main"
    :initial-values="initialValues"
    v-slot="{ values, validate, validateField }"
    :validation-schema="schema"
  >
    <Field
      as="div"
      :name="key.toString()"
      v-slot="{ field }"
      class="form-filed"
      v-for="(item, key) in formData"
      :style="lineStyle"
    >
      <label :style="labelStyle">
        <img
          v-show="item.required"
          :style="{ width: requiredSize, height: requiredSize }"
          :src="publicUrl(`/images/required.png`)"
        />
        <span>{{ item.label }}</span></label
      >
      <div
        class="container"
        :style="{ width: item.width ? item.width : 'auto' }"
      >
        <template v-if="item.type === 'input'">
          <div
            class="right-content"
            :style="{
              background: background,
              paddingRight: `.1rem`,
              paddingLeft: `.1rem`,
              height: item.height ? item.height : inputHeight,
              ...contentStyle,
            }"
          >
            <input
              :disabled="item.disabled"
              v-bind="{ ...(item.vBind ? item.vBind : {}), ...field }"
              :placeholder="item.placeholder ? item.placeholder : `请输入内容`"
            />
          </div>
        </template>
        <template v-else-if="item.type === 'oneUpload'">
          <div class="right-content">
            <OneUpload
              @change="
                ($event) =>
                valChange($event, values, key.toString(), validateField)
              "
              v-bind="item.vBind ? item.vBind : {}"
            />
          </div>
        </template>
        <template v-else-if="item.type === 'select'">
          <div
            class="right-content"
            :style="{
              background: background,
              width: item.width ? item.width : 'auto',
              height: item.height ? item.height : inputHeight,
            }"
          >
            <Select :placeholder="item.placeholder" @change="($event:string | number | undefined)=>valChange($event, values, key.toString(), validateField)" v-bind="item.vBind ? item.vBind : {}" />
          </div>
        </template>
        <template v-else-if="item.type === 'switch'"> </template>
        <template v-else-if="item.type === 'textarea'"> </template>

        <ErrorMessage :name="key.toString()" class="error-msg" />
      </div>
    </Field>

    <div class="button">
      <slot name="button" :values="values" :validate="validate"></slot>
    </div>
  </Form>
</template>
<script setup lang="ts" name="">
import { ref, computed, CSSProperties,onMounted } from "vue";
import { FormData } from "./interface";
import { Form, Field, ErrorMessage } from "vee-validate";
import { publicUrl } from "@/utils/util";
import OneUpload from "./components/OneUpload/index.vue";
import Select from "@/components/Select/index.vue";

interface Props {
  formData?: FormData;        //表格数据
  labelWidth?: string;        //label左边标题
  inputHeight?: string;       //输入框高度
  background?: string;        //背景颜色
  initialValues?: { [key: string]: any };  //默认数据
  spacing?: string;                          //表单竖向间隔                     
  labelAlign?: "center" | "left" | "right";  //label显示方向
  labelCss?: CSSProperties;                   //label css自定义
  requiredSize?: string;                      // required图标大小
  lineCss?: CSSProperties;                    //一行数据css
  schema?: Record<string, any>;               //yup验证方式
  contentCss?: CSSProperties;                 //内容css
}

const form = ref<any>(null);





const props = withDefaults(defineProps<Props>(), {
  formData: () => {
    return {};
  },
  labelWidth: ".5rem",
  labelAlign: "left",
  background: "#f9f9f9",
  lineHeight: ".2rem",
  requiredSize: ".0755rem",
  inputHeight: ".2rem",
  spacing: "0.2rem",
  schema: () => {
    return {};
  },
  initialValues: () => {
    return {};
  },
  labelCss: () => {
    return {};
  },
  lineCss: () => {
    return {};
  },
  contentCss: () => {
    return {};
  },
});

const labelAlign = computed((): string => {
  switch (props.labelAlign) {
    default:
    case "left":
      return "flex-start";
    case "right":
      return "flex-end";
    case "center":
      return "center";
  }
});

const labelStyle = computed((): CSSProperties => {
  return {
    color: "#2d2d2d",
    fontSize: ".0885rem",
    fontWeight: 600,
    width: props.labelWidth,
    justifyContent: labelAlign.value,
    ...props.labelCss,
  };
});
const lineStyle = computed((): CSSProperties => {
  return {
    // height: props.lineHeight,
    marginBottom: props.spacing,
    ...props.lineCss,
  };
});

const contentStyle = computed((): CSSProperties => {
  return {
    border: "1px solid #e7e7e7",
    marginLeft: ".101rem",
    ...props.contentCss,
  };
});

const valChange = (
  baseStr: any,
  values: any,
  key: string,
  validateField: any
) => {
  values[key] = baseStr;
  validateField(key);
};

defineExpose({ form });


</script>
<style scoped lang="scss">
@import "./index.scss";
</style>
